import folium, os, random

import bokeh.models
# MY_PATH = os.path.expanduser('~\Documents\edbdata')
MY_PATH = r'C:\Users\Public\Documents\edbdata'
HTML_PATH = os.path.join(MY_PATH, 'tile.html')
cityCode = [
{ "adcode": 100000, "name": "全国"},
{ "adcode": 110000, "name": "北京市"},
{ "adcode": 120000, "name": "天津市"},
{ "adcode": 130000, "name": "河北省"},
{ "adcode": 140000, "name": "山西省"},
{ "adcode": 150000, "name": "内蒙古自治区"},
{ "adcode": 210000, "name": "辽宁省"},
{ "adcode": 220000, "name": "吉林省"},
{ "adcode": 230000, "name": "黑龙江省"},
{ "adcode": 310000, "name": "上海市"},
{ "adcode": 320000, "name": "江苏省"},
{ "adcode": 330000, "name": "浙江省"},
{ "adcode": 340000, "name": "安徽省"},
{ "adcode": 350000, "name": "福建省"},
{ "adcode": 360000, "name": "江西省"},
{ "adcode": 370000, "name": "山东省"},
{ "adcode": 410000, "name": "河南省"},
{ "adcode": 420000, "name": "湖北省"},
{ "adcode": 430000, "name": "湖南省"},
{ "adcode": 440000, "name": "广东省"},
{ "adcode": 450000, "name": "广西壮族自治区"},
{ "adcode": 460000, "name": "海南省"},
{ "adcode": 500000, "name": "重庆市"},
{ "adcode": 510000, "name": "四川省"},
{ "adcode": 520000, "name": "贵州省"},
{ "adcode": 530000, "name": "云南省"},
{ "adcode": 540000, "name": "西藏自治区"},
{ "adcode": 610000, "name": "陕西省"},
{ "adcode": 620000, "name": "甘肃省"},
{ "adcode": 630000, "name": "青海省"},
{ "adcode": 640000, "name": "宁夏回族自治区"},
{ "adcode": 650000, "name": "新疆维吾尔自治区"},
{ "adcode": 810000, "name": "香港特别行政区"},
{ "adcode": 820000, "name": "澳门特别行政区"},
{ "adcode": 411200, "name": "三门峡市"}
]

class MAP():
    TOOLTIP = '点击查看详情'
    def __init__(self, db, border, showInfo, shen, shi):
        self.db = db
        self.border = border
        self.showInfo = showInfo
        self.shen = shen
        self.shi = shi
        # ltype 1=底图什么都没 2=道路图  可以使用多层叠加的方法
        self.map_types = {'jiedao':'https://wprd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&&x={x}&y={y}&z={z}&scl=1&style=7',
                         'weixing':'http://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'}
        self.map_type = 'jiedao'
        # self.bokeh_data()

    def get_map(self, types, map_type):
        if map_type == '高德地图':
            # 制作选择图源功能 添加边界设置为中国 SW NE
            m = folium.Map(location=[34.76, 113.65], tiles=None, maxBounds=[(3, 73), (59, 136)], zoom_start=5, control_scale=True)
            # 创建底图层
            basemap = folium.TileLayer(tiles=self.map_types[self.map_type], name='重金属污染地图', attr='高德地图', min_zoom=4)
            basemap.add_to(m)

            self.set_marker(m, types)
            # 载入边界
            if self.border.isChecked():
                self.load_border(m)

            # 添加图层控制器
            folium.LayerControl().add_to(m)

            m.save(HTML_PATH)
            return HTML_PATH

        # 选择的是GEOJSON
        elif map_type == 'GeoJson':
            # 制作geojson底图
            geo_group = folium.FeatureGroup(name='GeoJson')
            shen = self.shen.currentText()
            shi = self.shi.currentText()
            if shi == '全部':
                if shen == '全部':
                    # 选择了全部地点
                    # 制作选择图源功能 添加边界设置为中国 SW NE
                    m = folium.Map(location=[34.76, 113.65], tiles=None, maxBounds=[(3, 73), (59, 136)], zoom_start=8, control_scale=True)
                    city_list = self.db.find('DISTINCT 城市')
                    for city_name in city_list:
                        _ = 'geojson/{}.json'.format(city_name.get('城市'))
                        _ = os.path.join(MY_PATH, _)
                        self.load_json(_, city_name.get('城市'), m, False)
                    # 载入点位信息
                    self.set_marker(m, types)
                    # 添加图层控制器
                    folium.LayerControl().add_to(m)
                    m.save(HTML_PATH)
                    return HTML_PATH

                else:
                    # 选择了某一个省的全部市区
                    # 制作选择图源功能 添加边界设置为中国 SW NE
                    m = folium.Map(location=[34.76, 113.65], tiles=None, maxBounds=[(3, 73), (59, 136)], zoom_start=8, control_scale=True)
                    city_list = self.db.find('DISTINCT 城市',' WHERE 省份=\'{}\''.format(shen))
                    for city_name in city_list:
                        _ = 'geojson/{}.json'.format(city_name.get('城市'))
                        _ = os.path.join(MY_PATH, _)
                        self.load_json(_, city_name.get('城市'), m, False)
                    # 载入点位信息
                    self.set_marker(m, types)
                    # 添加图层控制器
                    folium.LayerControl().add_to(m)
                    m.save(HTML_PATH)
                    return HTML_PATH
            else:
                # 选择了某一个具体的市区
                # 制作选择图源功能 添加边界设置为中国 SW NE
                m = folium.Map(location=[34.76, 113.65], tiles=None, maxBounds=[(3, 73), (59, 136)], zoom_start=8, control_scale=True)
                _ = 'geojson/{}.json'.format(shi)
                _ = os.path.join(MY_PATH, _)
                self.load_json(_, shi, m, False)
                # 设置点位信息
                self.set_marker(m, types)
                # 添加图层控制器
                folium.LayerControl().add_to(m)
                m.save(HTML_PATH)
                return HTML_PATH

    def load_border(self, m):
        click = False
        # outline = folium.FeatureGroup(name='轮廓线')
        # 载入郑州市
        self.load_feild(os.path.join(MY_PATH, 'geojson/郑州市.json'), '郑州市轮廓线', m, click)
        # 载入中国边界
        self.load_feild(os.path.join(MY_PATH, 'geojson/中华人民共和国.json'), '中华人民共和国', m, click)


    def load_feild(self,path, name, m, click):
        with open(path, 'r', encoding='utf8') as f:
            data = f.read()
            folium.GeoJson(data, name=name, zoom_on_click=click).add_to(m)

    def load_json(self,path, name, m, click):
        with open(path, 'r', encoding='utf8') as f:
            data = f.read()
            folium.Choropleth(data, name=name, zoom_on_click=click, fill_color=self.random_color(), fill_opacity=0.5,
                              nan_fill_opacity=0.01, highlight=True).add_to(m)

    def get_data_from_db(self, types):
        query = ['ID','省份', '城市', '点位名称', '经度', '纬度']
        query += types

        # 下面这一行把query格式化成正确的SQL语法，用逗号连接
        _ = " ,".join(query)
        condiction, flag = self.get_selector_state()
        # 传给find函数 如果限制器开启了，则传入限制其参数
        if flag:
            result = self.db.find(_, condiction)
        else:
            result = self.db.find(_)

        return list(result)

    def get_selector_state(self):
        # 检查限制器的选项
        flag = False
        condiction = ' WHERE'
        if not self.shen.currentText() == '全部':
            flag = True
            condiction += ' 省份=\''
            condiction += self.shen.currentText()
            condiction += '\''
        if not self.shi.currentText() == '全部':
            if flag:
                condiction += ' AND'
            else:
                flag = True
            condiction += ' 城市=\''
            condiction += self.shi.currentText()
            condiction += '\''
        return condiction, flag

    def set_marker(self, m, types):
        # 判断是否要常显示详情
        if self.showInfo.isChecked():
            trigger = True
        else:
            trigger = False
        _ = '<p>省份：{}</br>城市：{}</br>点位：{}</br>'
        for type in types:
            _ += "{}：{{}}</br>".format(type)
        _ += '</p>'
        point_group = folium.FeatureGroup(name='点位信息')
        # 遍历所有的结果
        for value in self.get_data_from_db(types):
            # print(value)
            # 纬度 经度
            info = '<p>省份：{}</br>'.format(value['省份'])
            info += '城市：{}</br>'.format(value['城市'])
            info += '点位名称：{}</br>'.format(value['点位名称'])
            for type in types:
                info += '{}：{}</br>'.format(type, value[type])
            info += '</p>'
            # show 属性会被设置为trigger的值 用于控制是否需要单击显示详情
            # folium.Marker(
            #     [value['纬度'], value['经度']], popup=folium.Popup(info, max_width=500, show=trigger, sticky=trigger), tooltip=self.TOOLTIP
            #  ).add_to(m)
            folium.CircleMarker((value['纬度'], value['经度']), radius=5, color="#3186cc", fill=True, fill_color="#3186cc"
                                ,  popup=folium.Popup(info, max_width=500, show=trigger, sticky=trigger), tooltip=value['点位名称'] + '<br>' + self.TOOLTIP).add_to(point_group)
        point_group.add_to(m)

    def random_color(self):
        colors1 = '0123456789ABCDEF'
        num = "#"
        for i in range(6):
            num += random.choice(colors1)
        return num
    # def bokeh_data(self):
    #     # with open('./data/guo.json','r', encoding='utf8') as f:
    #     #     data = json.load(f)
    #     import xyzservices as xyz
    #     from bokeh.plotting import figure, show
    #     from bokeh.tile_providers import get_provider
    #     from bokeh import models
    #     x = xyz.TileProvider(name='高德地图', url='https://wprd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&&x={x}&y={y}&z={z}&scl=1&style=7'
    #                          , attribution='高德地图')
    #
    #     tile_provider = get_provider(x)
    #
    #     # range bounds supplied in web mercator coordinates
    #     p = figure(x_range=(-2000000, 6000000), y_range=(-1000000, 7000000),
    #                x_axis_type="mercator", y_axis_type="mercator", output_backend="webgl")
    #     p.add_tile(tile_provider)
    #     s1 = models.Scatter()
    #     show(p)